<?php
/**
 * 
 * Helper for building CSS-based forms.
 * 
 * @category Solar
 * 
 * @package Solar_View
 * 
 * @author Paul M. Jones <pmjones@solarphp.com>
 * 
 * @license http://opensource.org/licenses/bsd-license.php BSD
 * 
 * @version $Id: Form.php 1877 2006-09-30 19:33:52Z pmjones $
 * 
 */

/**
 * Needed for Solar_Form instanceof comparisons.
 */
Solar::loadClass('Solar_Form');

/**
 * Solar_View_Helper
 */
Solar::loadClass('Solar_View_Helper_Form');

/**
 * 
 * Helper for building CSS-based forms.
 * 
 * This is a fluent class; all method calls except fetch() return
 * $this, which means you can chain method calls for easier readability.
 * 
 * @category Solar
 * 
 * @package Solar_View
 * 
 * @author Paul M. Jones <pmjones@solarphp.com>
 * 
 */
class Domain51_View_Helper_Form extends Solar_View_Helper_Form {
    /**
     * 
     * User-provided configuration values.
     * 
     * @var array
     */
    protected $_Domain51_View_Helper_Form = array(
        'attribs' => array(),
    );
    
    /**
     * 
     * Constructor.
     * 
     * @param array $config User-provided configuration values.
     * 
     */
    public function __construct($config = null)
    {
        parent::__construct($config);
    }
    
    /**
     * 
     * Adds a single element to the form.
     * 
     * @param array $info The element information.
     * 
     * @return Domain51_View_Helper_Form
     * 
     */
    public function addElement($info)
    {
        $info = array_merge($this->_default_info, $info);
        
        if (empty($info['type'])) {
            throw $this->_exception('ERR_NO_ELEMENT_TYPE', $info);
        }
        
        if (empty($info['name'])) {
            throw $this->_exception('ERR_NO_ELEMENT_NAME', $info);
        }
        
        // auto-set ID?
        if (empty($info['attribs']['id'])) {
            // convert name[key][subkey] to name-key-subkey
            $info['attribs']['id'] = str_replace(
                    array('[', ']'),
                    array('-', ''),
                    $info['name']
            );
        }
        
        // is this id already in use?
        $id = $info['attribs']['id'];
        if (empty($this->_id_count[$id])) {
            // not used yet, start tracking it
            $this->_id_count[$id] = 1;
        } else {
            // already in use, increment the count.
            // e.g., 'this-id' becomes 'this-id-1',
            // next one is 'this-id-2', etc.
            $id .= "-" . $this->_id_count[$id] ++;
            $info['attribs']['id'] = $id;
        }
        
        // auto-set CSS classes for the element?
        $this->_doAutoSetCss($info);
        
        // place in the stack, or as hidden?
        if (strtolower($info['type']) == 'hidden') {
            // hidden elements are a special case
            $this->_hidden[] = $info;
        } else {
            // non-hidden element
            $this->_stack[] = array('element', $info);
        }
        
        return $this;
    }
    
    /**
     * Handle adding auto-set CSS classes for element
     *
     * @param   array
     * @see     addElement()
     */
    protected function _doAutoSetCss(&$info) {
        if (empty($info['attribs']['class'])) {
            // get a CSS class for the element type
            if (! empty($this->_css_class[$info['type']])) {
                $info['attribs']['class'] = $this->_css_class[$info['type']];
            } else {
                $info['attribs']['class'] = '';
            }
            
            // also use the element ID for further overrides
            $info['attribs']['class'] .= ' ' . $info['attribs']['id'];
            
            // passed validation?
            if ($info['status'] === true) {
                $info['attribs']['class'] .= ' ' . $this->_css_class['success'];
            }
            
            // failed validation?
            if ($info['status'] === false) {
                $info['attribs']['class'] .= ' ' . $this->_css_class['failure'];
            }
            
            // required?
            if ($info['require']) {
                $info['attribs']['class'] .= ' ' . $this->_css_class['require'];
            }
        }
    }
}

?>
